/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
 * Description: SMAP Tiering Memory Solution: wrapper header
 */

#ifndef _SMAP_MIGRATE_WRAPPER_H_
#define _SMAP_MIGRATE_WRAPPER_H_

#include <asm/current.h>
#include <asm-generic/errno-base.h>
#include <linux/migrate.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/nodemask.h>
#include <linux/kernel.h>
#include <linux/pgtable.h>
#include <linux/sched.h>
#include <linux/lockdep.h>
#include <linux/page-flags.h>
#include <linux/mmdebug.h>
#include <linux/page_ref.h>
#include <linux/oom.h>
#include <linux/pageblock-flags.h>
#include <linux/bitops.h>
#include <linux/mmzone.h>
#include <linux/gfp.h>
#include <linux/numa.h>
#include <linux/cpuset.h>
#include <linux/spinlock_types.h>
#include <linux/mm_types.h>
#include <linux/rmap.h>
#include <linux/swapops.h>
#include <linux/kprobes.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/ioport.h>

#define OBMM_MAX_PRIV_LEN 512

struct obmm_ownership_info {
	uint32_t *mem_state_arr;
	int npages;
};

enum obmm_region_type { OBMM_EXPORT_REGION, OBMM_IMPORT_REGION };

struct obmm_region {
	/* unique within host -- can be used as an access handle */
	int regionid;

	/* import or export */
	enum obmm_region_type type;

	unsigned long flags;

	struct cdev cdevice;
	struct device device;

	/* number of kernel users which has access to this data structure */
	atomic_t user_count;
	/* number of valid open() of this region */
	atomic_t open_count;

	/* the total size of all memory segments included in meminfo */
	u64 mem_size;
	bool cacheable;

	/* track mapping of a region */
	spinlock_t pid_lock;
	/* a list of struct obmm_pid_info: processes which has mapped this region */
	struct list_head pid_list;

	struct obmm_ownership_info *ownership_info;
	/* protect ownership_info */
	struct mutex state_mutex;

	/* regions are chained into a list for management */
	struct list_head node;

	unsigned int priv_len;
	unsigned char priv[OBMM_MAX_PRIV_LEN];
};

struct obmm_import_region {
	struct obmm_region region;

	/* uba, tokenid and dcna is not used when the system is in decoder_prefilled mode */
	u64 uba;
	unsigned int tokenid;
	u32 dcna;

	u32 scna;

	/* resource generated by ubus driver */
	struct resource *parent;
	/* imported PA range */
	struct resource *resource;
	u64 pa;

	/* imported NUMA node */
	int numa_id;

	/* handle to manage associated preimport range */
	void *preimport_handle;
};

/* Extended information of a byte address */
struct obmm_ext_addr {
	/* OBMM related */
	enum obmm_region_type region_type;
	u32 regionid;
	u64 offset;

	/* UB bus related */
	u32 tid;
	u64 uba;

	/* host machine related */
	s32 numa_id;
	u64 pa;
};

struct folio *smap_alloc_huge_page_node(struct folio *folio, int nid,
					bool is_mig_back);

#endif
